//---------------------------------------------------------------------------
class PlayerManager;
class PlayerInfo;
#ifndef player_infoH
#define player_infoH
#include <map>
#include <math.h>
#include <vector>
#include <string>
#include <iostream>
#include <process.h>
using namespace std;
#include "structs.h"
#include "servercontrol.h"
#include "addlog.h"
#include "teleport.h"
#include "IniFile.h"
#include "utils.h"
//#include "Player_Window.h"
//---------------------------------------------------------------------------

PlayerManager* Manager();
void SetManager(PlayerManager* manager);

//---------------------------------------------------------------------------
class LocList
{
private:
	map<string,D3DXVECTOR3> default_locs;
	map<string,map<string,D3DXVECTOR3>> locs_per_map;
public:
	void Save();
	void Load();
	string ClosestLoc(D3DXVECTOR3 coord);
	// returns the appropriate location that is in This map. If it's not found, it then checks default locations that are for Any map. i.e. Origin.
	// If the location is not found, BAD_LOC is returned. (i REALLY suggest not using it then, since bad_loc is INFINITY)
	D3DXVECTOR3 GetLoc(string loc);
	void AddLoc(string loc, D3DXVECTOR3 coord);
};


// Notice: CDHASH was replaced with string, since a string is easier to manage instead of a non-null terminated c_str.
//struct CDHASH
//{
//	CDHASH();
//	CDHASH(CDHASH2);
//	char hash[32];
//
//};
//bool operator<(const CDHASH left, const CDHASH right);

// Personal info concerning players of the server.
// ID'd by cd hash, possibly differentiated by name or ip (or close/wildcard matching),
// and each individualized player can have settings for himself.
// Settings include: admin level, handicap - Shield, handicap - health, handicap - speed, handicap - ammo, handicap - other ammo,
// chat-allowed (team, global), and Global join message, and personal join message.
class PlayerInfo
{
public:
	PlayerInfo();
	void OnSpawn(playerindex my_ind);
	void AddName(string NewName);
	//vector<wstring> names; // actually, I don't think that I'll bother storing them. waste of space.
	//vector<string> ips;	 // names or ips here. Not needed, since the logs store that anyway, right?

	// handicap multipliers
	float handicap_shield;
	float handicap_health;
	float handicap_speed;
	float handicap_ammo;
	float handicap_clip;

	// join messages
	string join_global;
	string join_private;

	/*
	Admin powers descriptions: (all incremental). No commands can be used against other admins.
	1: lowest level - barest abilities, such as can just do sv_say, textban, or teamswitch (but not against zombification). (sv_players is a given, lol)
	2: can do general moderating things: sv_kick, tempban (custom command, which has a set timelimit), and kill
	3: higher powered moderator: sv_mapreset, tempban [level], and can unban (custom commands: banlist, unban - which can only unban less punished players).
	4: lower level admin: sv_ban, sv_unban, sv_banlist, teamswitch against zombification, playerlist (custom command that shows more info), and some other cmds; Still no settings influence.
	5: general admin: can do cmdfile (limited choices, and cannot add new files), other general administrative abilities.
	6: higher level admin: any admin ability, practically full server control, but virtually no cheating abilities.
	7: lower level haxor: can do some lower-awesome grade cheats, such as setammo, teleport, speed, others...
	8: general haxor: can do most cheats
	9: high power haxor: may do virtually anything with devmode, but still some restrictions.
	10: Wizard: if you're 10 or above, no command restrictions, but still cannot do anything to other admins. May change admin levels on other players up to 9, and can only un-admin players they added.
	11: First Wizard: can change anyones admin level, up or down, but still only up to 9.
	999: Creator/God: no check whatsoever. Reserved for Abyll, since he can do anything. (there's also a few super-special commands here)
	 */
	short admin_powers;

	// misc data
	bool can_chat;
	bool last_team;

	unsigned short botdetects;


};

class PlayerManager
{
public:
	~PlayerManager();
	// <cd hash, info>
	map<string,PlayerInfo> Players;

	// <nickname, hash>
	map<string,string> nicknames;

	// Saves players out in seperate files, ONLY if they have anything worth saving. That is, if something is the default then it's not included.
	string save_dir;
	string players_dir;
	string locations_dir;
	string save_ext;
	string players_ext;
	void SavePlayers();
	void LoadPlayers();

	//stored references to watch changes on the players themselves.
	short kills[16];
	short deaths[16];
	bool dead[16];
	short assists[16];
	bool team[16];
	bool wason[16];

	// misc. data
	bool zombification;
	bool botcheck;
	float aim_sensitivity;
	//float snap_sensitivity;

	// Teleport stuff
	LocList teleport;


	PlayerInfo* GetPlayerInfo(string hash); // Not really necessary - just use this.map[hash]
	PlayerInfo* GetPlayerInfo(playerindex pl_ind, bool ignoreOff=false); // this.map[ (currentplayers[pl_ind].hash) ]. Returns NULL if that slot is empty (not on).
	PlayerInfo* GetInfoByNickname(string nickname);
	Static_Player* GetPlayerByNickname(string nickname);
	void AddNickname(playerindex pl_ind, string nickname);


	// Various SERVER Events.
	// when they respawn, they need to have their handicaps set. (And if i get around to the part, count up kills or w/e. but that's mostly left to the playertracker through log. Maybe just add an SV_NOTE.)
	void PlayerSpawn(playerindex pl_index);
	void PlayerSpawn(Static_Player* pl);
	void OnDeath(Static_Player* pl);
	void PlayerJoin(playerindex ind);
	void PlayerQuit(playerindex ind);

	void Zombificator();
	void ZombieReset();
	//void HumanCheck(playerindex pl_ind);

	void CheckForSnap();
};

// PRIMARY thread, that watches for joins, kills, and quits, and then calls other event functions.
void PlayerWatcher(void* param);
unsigned int __stdcall PlayerDeath(void* param);


#endif